import { Legion } from "../struct/Legion";
import { Player } from "../struct/Player";
import { LegionInfo } from "../struct/LegionInfo";
import { CDLegionLevel } from "../excel/CDLegionLevel";
import { CDLegionPosition } from "../excel/CDLegionPosition";
import { CDLegionShop } from "../excel/CDLegionShop";
import { CDLegionDonation } from "../excel/CDLegionDonation";
import { CDLegionGlobal } from "../excel/CDLegionGlobal";
import { E_ItemID } from "../defs/item/E_ItemID";
const NoneLegionId = -1;
export abstract class SDLegion {
    public static readonly RANK_NAME = "LegionRank";
    public static readonly LEVEL_RANK_NAME = "LegionLevelRank";
    /**排行榜长度 */
    public static readonly RANK_COUNT = 100;
    /**
     * 转换周一到周日 为0-6
     * @param date 日期
     * @returns 0-6
     */
    public static getDayOfWeek(date: Date): number {
        let day = date.getDay();
        if (day === 0) {
            day = 6;
        }
        else {
            day--;
        }
        return day;
    }
    /**
     * 获取本周周一零点时间戳
     * @param date 日期
     * @returns 本周周一零点时间戳
     */
    public static getWeekMondayTime(date: Date | string | number): number {
        let todayDate = new Date(date);
        //获取本周周一零点时间戳
        let weekDay = this.getDayOfWeek(todayDate);
        let weekMonday = todayDate.getDate() - weekDay;
        let weekMondayDate = new Date(todayDate.setDate(weekMonday));
        weekMondayDate.setHours(0, 0, 0, 0);
        return weekMondayDate.getTime();
    }
    //重置每周贡献
    public static resetWeekContribution(player: Player) {
        //校验本周贡献重置
        let todayDonateTime = player.legion.weekContributionTime;
        if (todayDonateTime) {
            let weekMondayTime = this.getWeekMondayTime(new Date().getTime());
            let donateTime = this.getWeekMondayTime(todayDonateTime);
            if (weekMondayTime != donateTime) {
                //重置今日捐献次数
                player.legion.weekContributionTime = weekMondayTime;
                player.legion.weekContribution = 0;
            }
        } else {
            player.legion.weekContributionTime = Date.now();
        }
        this.resetBuyItemTime(player);
        this.resetDonateContribution(player);

    }
    //重置每周捐献次数
    public static resetDonateContribution(player: Player) {
        //校验今日捐献次数
        let todayDonateTime = player.legion.lastDonateTime;
        if (todayDonateTime) {
            let today = Date.now();
            let todayDate = new Date(today);
            let todayTime = todayDate.getDate();
            let donateTime = new Date(todayDonateTime);
            let donateTimeDate = donateTime.getDate();
            if (todayTime != donateTimeDate) {
                //重置今日捐献次数
                player.legion.lastDonateTime = todayDonateTime;
                player.legion.clearDonateContributionMap();
            }
        } else {
            player.legion.lastDonateTime = Date.now();
        }
    }
    //重置购买物品时间
    public static resetBuyItemTime(player: Player) {
        //校验购买物品时间
        let todayBuyItemTime = player.legion.lastBuyItemTime;
        if (todayBuyItemTime) {
            let today = Date.now();
            let todayDate = new Date(today);
            let todayTime = todayDate.getDate();
            let donateTime = new Date(todayBuyItemTime);
            let donateTimeDate = donateTime.getDate();
            if (todayTime != donateTimeDate) {
                //重置今日购买物品次数
                player.legion.lastBuyItemTime = today;
                player.legion.clearBuyItemNumsMap();
            }
        } else {
            player.legion.lastBuyItemTime = Date.now();
        }
    }
    /**
     * 检查创建军团的条件是否满足
     * @param player 玩家对象，包含玩家信息和物品数据
     * @param legionName 要创建的军团名称
     * @returns 返回检查结果对象，包含状态码和错误信息
     *          c: 状态码(0表示成功，负数表示各种错误)
     *          e: 错误描述信息
     */
    public static checkCreateLegion(player: Player, legionName: string): { c: number, e: string } {
        if (!legionName || typeof legionName !== 'string') {
            return { c: -1, e: "名称格式错误" };
        }
        //获取军团名称最小长度
        let config4 = CDLegionGlobal.getData(6);
        //获取军团名称最大长度
        let config5 = CDLegionGlobal.getData(7);
        if (legionName.length < config4.value || legionName.length > config5.value) {
            return { c: -2, e: "名称格式错误" };
        }
        // 检查名称是否包含非法字符
        const validNameRegex = /^[\u4e00-\u9fa5a-zA-Z0-9_\-\s]+$/;
        if (!validNameRegex.test(legionName)) {
            return { c: -3, e: "名称包含非法字符" };
        }

        //获取创建军团所需等级配置
        let config = CDLegionGlobal.getData(1);
        //判断等级是否大于等于10
        if (player.playerInfo.level < config.value) {
            return { c: -4, e: "等级不足" };
        }
        //获取军团创建所需金币
        let config2 = CDLegionGlobal.getData(2);
        //获取用户当前的铜钱数量
        let coin = player.getItemNum(E_ItemID.Copper);

        if (coin < config2.value) {
            return { c: -5, e: "铜币不足" };
        }
        //获取创建军团所需钻石
        let config3 = CDLegionGlobal.getData(3);
        //获取用户当前的钻石数量
        let diamond = player.getItemNum(E_ItemID.Diamonds);
        if (diamond < config3.value) {
            return { c: -6, e: "钻石不足" };
        }
        //判断用户是否用于军团
        if (player.legion && player.legion.legionId > 0) {
            return {
                c: -7,
                e: "已加入军团"
            };
        }
        return { c: 0, e: "创建成功" };
    }
    //军团转军团信息
    public static toLegionInfo(legin: Legion): string {
        let snapshot = LegionInfo.create(legin.stringify(true));
        snapshot.totalMember = legin.getMembersKeys().length;
        let config = CDLegionLevel.getData(legin.legionLevel);
        snapshot.maxMember = config.memberNum;
        let jsonx = snapshot.stringify(true);
        snapshot.destroy();
        return jsonx;
    }
    /**
     * 检查军团商店商品购买条件
     * @param player 玩家对象
     * @param legion 军团对象
     * @param itemId 商品ID
     * @param buyTimes 购买次数
     * @returns 返回检查结果对象 {c: 状态码, e: 错误信息}
     *          c=0表示成功，其他值为错误码
     *          -2: 商品不存在
     *          -3: 军团等级不足
     *          -4: 购买数量错误
     *          -5: 货币不足
     *          -6: 购买次数已达上限
     */
    public static checkBuyItem(player: Player, legion: Legion, itemId: number, buyTimes: number): { c: number, e: string } {
        // 获取商店配置
        const shopConfig = CDLegionShop.getData(itemId);
        if (!shopConfig) {
            return { c: -2, e: "商品不存在" };
        }
        if (shopConfig.legionLv > legion.legionLevel) {
            return { c: -3, e: "军团等级不足" };
        }
        // 判断是否有足够的数量
        if (buyTimes < 0) {
            return { c: -4, e: "购买数量错误" };
        }
        //是否购买达到上限
        let buyNum = player.legion.getBuyItemNums(itemId);
        if (buyNum >= shopConfig.itemNum) {
            return { c: -6, e: "购买次数已达上限" };
        }
        //消耗数量
        let cost = shopConfig.costItemNum * buyTimes;
        //消耗货币配置
        const itemCount = player.getItemNum(shopConfig.costItemId);
        if (cost > itemCount) {
            return { c: -5, e: "货币不足" };
        }
        return { c: 0, e: "购买成功" };
    }
    /**
     * 校验捐献条件
     */
    public static checkDonate(player: Player, donationType: number): { c: number, e: string } {
        let msg: { c: number, e: string } = {
            c: 0,
            e: "成功"
        };
        if (!player || !player.legion || player.legion.legionId <= 0) {
            msg = {
                c: -1,
                e: "用户没有加入军团"
            };
            return msg;
        }
        this.resetWeekContribution(player);
        // 获取捐献配置
        const donationConfig = CDLegionDonation.getData(donationType);
        if (!donationConfig) {
            return { c: -2, e: "捐献类型不存在" };
        }
        //获取玩家今日捐献次数
        let todayDonateNum = player.legion.getDonateContribution(donationType);
        if (todayDonateNum >= donationConfig.dailyLimit) {
            msg = {
                c: -4,
                e: "今日捐献次数已达上限"
            };
            return msg;
        }
        if (donationConfig.costItemId) {
            let itemNum = player.getItemNum(donationConfig.costItemId);
            if (itemNum < donationConfig.costItemNum) {
                msg = {
                    c: -3,
                    e: "捐献贡献物品不足"
                };
                return msg;
            }
        }
        return msg;
    }
    /**
     * 检查军团设置职位权限
     * @param legion 军团对象
     * @param mgrId 管理者ID
     * @param playerId 玩家ID
     * @param position 职位编号
     * @returns 返回权限检查结果对象 {c: 状态码, e: 错误信息}
     * @description 验证管理者是否有权限对指定玩家进行职位操作，包括：
     * - 军团是否存在
     * - 职位配置是否存在
     * - 管理者是否为军团成员
     * - 操作权限验证(非军团领袖或操作自己/领袖时无权限)
     * - 目标玩家是否为军团成员
     * - 目标职位是否已满
     */
    public static checkSetPostionPermission(legion: Legion, mgrId: number, playerId: number, position: number): { c: number, e: string } {
        let msg: { c: number, e: string } = {
            c: 0,
            e: "成功"
        };
        if (!legion) {
            msg = {
                c: 3,
                e: "军团不存在"
            };
        }
        let setPositionCfg = CDLegionPosition.getData(position);
        if (!setPositionCfg) {
            msg = {
                c: 8,
                e: "暂无职位"
            };
        }
        let MgrMember = legion.getMembers(mgrId);
        //成员已存在
        if (!MgrMember) {
            msg = {
                c: 5,
                e: "您不是该军团的成员"
            };
        }
        // let positionCfg = CDLegionPosition.getData(MgrMember.position);
        if (legion.legionLeader != mgrId || playerId == mgrId || playerId == legion.legionLeader) {
            msg = {
                c: 6,
                e: "无权限"
            };
        }
        let member = legion.getMembers(playerId);
        //成员已存在
        if (!member) {
            msg = {
                c: 7,
                e: "军团成员不已存在"
            };
        }
        if (setPositionCfg.positionNum != 0) {
            let posNum = legion.getMembersValues().reduce((pre, cur) => {
                if (cur.position == setPositionCfg.positionNum) {
                    pre++;
                }
                return pre;
            }, 0);
            if (setPositionCfg.positionNum < posNum) {
                msg = {
                    c: 9,
                    e: "职位已满"
                };
            }
        }
        return msg;
    }
    /**
     * 检查移除军团成员的权限
     * @param legion 军团对象
     * @param mgrId 操作者ID
     * @param playerId 被操作玩家ID
     * @returns 返回操作结果对象 {c: 状态码, e: 错误信息}
     * @remarks
     * - 状态码3: 军团不存在
     * - 状态码5: 操作者非军团成员
     * - 状态码6: 无权限/无踢出权限
     * - 状态码7: 目标成员不存在
     * - 状态码8: 无权限踢出高于自己职位的成员
     */
    public static checkRemovePlayerPermission(legion: Legion, mgrId: number, playerId: number): { c: number, e: string } {
        let msg: { c: number, e: string } = {
            c: 0,
            e: "成功"
        };

        if (!legion) {
            msg = {
                c: 3,
                e: "军团不存在"
            };
        }
        let MgrMember = legion.getMembers(mgrId);
        //成员已存在
        if (!MgrMember) {
            msg = {
                c: 5,
                e: "您不是该军团的成员"
            };
        }
        if (legion.legionLeader != mgrId || playerId == mgrId || playerId == legion.legionLeader) {
            msg = {
                c: 6,
                e: "无权限"
            };
        }
        let member = legion.getMembers(playerId);
        //成员已存在
        if (!member) {
            msg = {
                c: 7,
                e: "军团成员不已存在"
            };
        }
        let positionCfg = CDLegionPosition.getData(MgrMember.position);
        if (MgrMember.position < member.position && positionCfg.kickOfficer == 0) {
            msg = {
                c: 8,
                e: "无权限踢出高于自己职位"

            };
        }
        if (positionCfg.kickMember == 0) {
            msg = {
                c: 6,
                e: "无踢出会员权限"
            };
        }
        return msg;
    }
    /**
     * 检查军团申请状态
     * @param legion 军团对象
     * @param mgrId 管理员ID
     * @param playerId 玩家ID
     * @returns 返回检查结果对象 {c: 状态码, e: 错误信息}
     * @remarks
     * - 状态码说明:
     *   - 0: 成功
     *   - 3: 军团不存在
     *   - 5: 申请记录不存在
     *   - 6: 管理员未加入该军团
     *   - 7: 无审批权限
     */
    public static checkLegionApply(legion: Legion, mgrId: number, playerId: number): { c: number, e: string } {
        let msg: { c: number, e: string } = {
            c: 0,
            e: "成功"
        };

        if (!legion) {
            msg = {
                c: 3,
                e: "军团不存在"
            };
        }
        let mgrMbr = legion.getMembers(mgrId);
        if (!mgrMbr) {
            msg = {
                c: 6,
                e: "管理员未加入该军团"
            };
        }
        let positionCfg = CDLegionPosition.getData(mgrMbr.position);
        if (positionCfg.passMember == 0) {
            msg = {
                c: 7,
                e: "无审批权限"
            };
        }
        let apply = legion.getApplications(playerId); //申请列表
        if (!apply) {
            msg = {
                c: 5,
                e: "申请记录不存在"
            };
        }
        return msg;
    }
    /**
     * 检查并验证军团公告设置权限
     * @param legion 军团对象
     * @param mgrId 管理员ID
     * @returns 返回验证结果对象，包含状态码(c)和错误信息(e)
     * @remarks
     * - c=0, e="成功" 表示验证通过
     * - c=3 表示军团不存在
     * - c=6 表示管理员未加入该军团
     * - c=7 表示无权限修改
     */
    public static checkSetNotice(legion: Legion, mgrId: number): { c: number, e: string } {
        let msg: { c: number, e: string } = {
            c: 0,
            e: "成功"
        };

        if (!legion) {
            msg = {
                c: 3,
                e: "军团不存在"
            };
        }
        let mbr = legion.getMembers(mgrId);
        if (!mbr) {
            msg = {
                c: 6,
                e: "管理员未加入该军团"
            };
        }
        let positionCfg = CDLegionPosition.getData(mbr.position);
        if (positionCfg.mark == 0) {
            msg = {
                c: 7,
                e: "无权限修改"
            };
        }
        return msg;
    }
    /**
     * 检查玩家是否可以加入军团
     * @param legion 目标军团对象
     * @param mgrId 管理ID
     * @param playerId 玩家ID
     * @returns 返回检查结果对象 {c: 状态码, e: 错误信息}
     *          - c=0 表示可以加入
     *          - c=4 表示军团成员已满
     *          - c=8 表示成员已存在
     */
    public static checkApplyJoin(legion: Legion, mgrId: number, playerId: number): { c: number, e: string } {
        let msg = this.checkLegionApply(legion, mgrId, playerId);
        if (msg.c != 0) {
            return msg;
        }
        //当前军团成员数量
        let config = CDLegionLevel.getData(legion.legionLevel);
        let memberCount = legion.getMembersKeys().length;
        if (memberCount >= config.memberNum) {
            msg = {
                c: 4,
                e: "军团成员已满"
            };
        }
        let member = legion.getMembers(playerId);
        //成员已存在
        if (member) {
            msg = {
                c: 8,
                e: "成员已存在"
            };
        }
        return msg;
    }


}
